package com.mychat.service.impl;


import com.mychat.entity.Constants;
import com.mychat.entity.dto.MessageSendDto;
import com.mychat.entity.dto.SysSettingDto;
import com.mychat.entity.dto.TokenUserInfoDto;
import com.mychat.entity.po.GroupInfo;
import com.mychat.entity.po.UserContact;
import com.mychat.entity.po.UserInfo;
import com.mychat.entity.query.*;
import com.mychat.enums.*;
import com.mychat.entity.vo.PaginationResultVO;
import com.mychat.entity.po.UserContactApply;
import com.mychat.exception.BusinessException;
import com.mychat.mappers.GroupInfoMapper;
import com.mychat.mappers.UserContactApplyMapper;
import com.mychat.mappers.UserContactMapper;
import com.mychat.mappers.UserInfoMapper;
import com.mychat.redis.RedisComponent;
import com.mychat.service.UserContactApplyService;
import com.mychat.service.UserContactService;
import com.mychat.utils.StringUtils;
import com.mychat.websocket.MessageHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.rmi.server.ExportException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
 * @Description:ServiceImpl
 * @auther:YYT
 * @date:2025/03/02
 */
@Service("userContactApplyService")
public class UserContactApplyServiceImpl implements UserContactApplyService {

	Logger logger = LoggerFactory.getLogger(UserContactApplyServiceImpl.class);

	@Resource
	private UserContactApplyMapper<UserContactApply, UserContactApplyQuery> userContactApplyMapper;

	@Resource
	private UserContactMapper<UserContact, UserContactQuery> userContactMapper;

	@Resource
	private UserContactService userContactService;

	@Resource
	private MessageHandler messageHandler;

	@Resource
    private GroupInfoMapper<GroupInfo, GroupInfoQuery> groupInfoMapper;

	@Resource
	private UserInfoMapper<UserInfo, UserInfoQuery> userInfoMapper;

	/**
	 * 根据条件查询列表
	 */
	@Override
	public List<UserContactApply> findListByParam(UserContactApplyQuery query) {
		return this.userContactApplyMapper.selectList(query);
	}

	/**
	 * 根据条件查询数量
	 */
	@Override
	public Integer findCountByParam(UserContactApplyQuery query) {
		return this.userContactApplyMapper.selectCount(query);
	}

	/**
	 * 分页查询
	 */
	@Override
	public PaginationResultVO<UserContactApply> findListByPage(UserContactApplyQuery query) {
		Integer count = this.findCountByParam(query);
		Integer pageSize = query.getPageSize() == null ? PageSize.SIZE15.getSize(): query.getPageSize();
		SimplePage page = new SimplePage(query.getPageNo(), count, pageSize);
		query.setSimplePage(page);
		List<UserContactApply> list = this.findListByParam(query);
		PaginationResultVO<UserContactApply> result = new PaginationResultVO<UserContactApply>(count, page.getPageSize(), page.getPageNo(), page.getPageTotal(), list);
		return result;
	}

	/**
	 * 新增
	 */
	@Override
	public Integer add(UserContactApply bean) {
		return this.userContactApplyMapper.insert(bean);
	}

	/**
	 * 批量新增
	 */
	@Override
	public Integer addBatch(List<UserContactApply> listBean) {
		if(listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userContactApplyMapper.insertBatch(listBean);
	}

	/**
	 * 批量新增或修改
	 */
	@Override
	public Integer addOrUpdateBatch(List<UserContactApply> listBean) {
		if(listBean == null || listBean.isEmpty()) {
			return 0;
		}
		return this.userContactApplyMapper.insertOrUpdateBatch(listBean);
	}

	/**
	 * 根据ApplyId查询
	 */
	@Override
	public UserContactApply getUserContactApplyByApplyId(Integer applyId) {
		return this.userContactApplyMapper.selectByApplyId(applyId);
	}

	/**
	 * 根据ApplyId更新
	 */
	@Override
	public Integer updateUserContactApplyByApplyId(UserContactApply bean, Integer applyId) {
		return this.userContactApplyMapper.updateByApplyId(bean, applyId);
	}

	/**
	 * 根据ApplyId删除
	 */
	@Override
	public Integer deleteUserContactApplyByApplyId(Integer applyId) {
		return this.userContactApplyMapper.deleteByApplyId(applyId);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Integer applyAdd(TokenUserInfoDto tokenUserInfoDto, String contactId, String applyInfo) throws BusinessException {
		UserContactTypeEnum typeEnum = UserContactTypeEnum.getEnumByPrefix(contactId.charAt(0) + "");
		if(null == typeEnum) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}
		// 申请人
		String applyUserId = tokenUserInfoDto.getUserId();

		// 默认申请信息
		applyInfo = StringUtils.isEmpty(applyInfo) ? String.format(Constants.APPLY_INFO_TEMPLATE, tokenUserInfoDto.getNickName())  : applyInfo;

		Long curTime = System.currentTimeMillis();

		Integer joinType = null;
		String receiveUserId = contactId;

		// 查询对方好友是否拉黑
		UserContact userContact = userContactMapper.selectByUserIdAndContactId(applyUserId, contactId);
		if(userContact != null && UserContactStatusEnum.BLACK_BY_FRIEND.getCode().equals(userContact.getStatus())) {
			throw new BusinessException("对方已经把你拉黑");
		}

		if(UserContactTypeEnum.GROUP == typeEnum) {
			GroupInfo groupInfo = groupInfoMapper.selectByGroupId(contactId);
			if(groupInfo == null || GroupInfoStatusEnum.DELETED.getCode().equals(groupInfo.getStatus())) {
				throw new BusinessException("群聊不存在或已经解散");
			}
			receiveUserId = groupInfo.getGroupOwnerId();
			joinType = groupInfo.getJoinType();
		} else {
			UserInfo userInfo = userInfoMapper.selectByUserId(contactId);
			if(userInfo == null) {
				throw new BusinessException(ResponseCodeEnum.CODE_600);
			}
			joinType = userInfo.getJoinType();
		}

		if(JoinTypeEnum.JOIN.getType().equals(joinType)) {
			userContactService.addContact(applyUserId, receiveUserId, contactId, typeEnum.getType(), applyInfo);
			return joinType;
		}

		UserContactApply dbApply = this.userContactApplyMapper.selectByApplyUserIdAndReceiveUserIdAndContactId(applyUserId, receiveUserId, contactId);
		if(dbApply == null) {
			UserContactApply apply = new UserContactApply();
			apply.setApplyUserId(applyUserId);
			apply.setReceiveUserId(receiveUserId);
			apply.setContactId(contactId);
			apply.setContactType(typeEnum.getType());
			apply.setLastApplyTime(curTime);
			apply.setStatus(UserContactApplyStatusEnum.INIT.getCode());
			apply.setApplyInfo(applyInfo);
			this.userContactApplyMapper.insert(apply);
		} else{
			// 更新状态
			UserContactApply apply = new UserContactApply();
			apply.setStatus(UserContactApplyStatusEnum.INIT.getCode());
			apply.setLastApplyTime(curTime);
			apply.setApplyInfo(applyInfo);
			this.userContactApplyMapper.updateByApplyUserIdAndReceiveUserIdAndContactId(apply, applyUserId, receiveUserId, contactId);
		}

		if(dbApply == null || !UserContactApplyStatusEnum.INIT.getCode().equals(dbApply.getStatus())) {
			// 发送ws消息
			MessageSendDto messageSendDto = new MessageSendDto();
			messageSendDto.setMessageType(MessageTypeEnum.CONTACT_APPLY.getType());
			messageSendDto.setMessageContent(applyInfo);
			messageSendDto.setContactId(contactId);
			messageHandler.sendMessage(messageSendDto);
		}
		return joinType;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void dealWithApply(String userId, Integer applyId, Integer status) throws BusinessException {
		UserContactApplyStatusEnum statusEnum = UserContactApplyStatusEnum.getEnumByStatus(status);
		if(statusEnum == null || UserContactApplyStatusEnum.INIT == statusEnum) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}
		UserContactApply applyInfo = this.userContactApplyMapper.selectByApplyId(applyId);
		if(applyInfo == null || !userId.equals(applyInfo.getReceiveUserId())) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}

		UserContactApply updateInfo = new UserContactApply();
		updateInfo.setStatus(statusEnum.getCode());
		updateInfo.setLastApplyTime(System.currentTimeMillis());

		UserContactApplyQuery applyQuery = new UserContactApplyQuery();
		applyQuery.setApplyId(applyId);
		applyQuery.setStatus(UserContactApplyStatusEnum.INIT.getCode());

		Integer count = this.userContactApplyMapper.updateByParam(updateInfo, applyQuery);

		if(count == 0) {
			throw new BusinessException(ResponseCodeEnum.CODE_600);
		}

		if(UserContactApplyStatusEnum.PASS.getCode().equals(statusEnum.getCode())) {
			// 同意
			userContactService.addContact(applyInfo.getApplyUserId(), applyInfo.getReceiveUserId(), applyInfo.getContactId(), applyInfo.getContactType(), applyInfo.getApplyInfo());
			return;
		}

		if(UserContactApplyStatusEnum.BLACKLIST == statusEnum) {
			// 拉黑
			Date currentDate = new Date();
			UserContact userContent = new UserContact();
			userContent.setUserId(applyInfo.getApplyUserId());
			userContent.setContactId(applyInfo.getContactId());
			userContent.setStatus(UserContactStatusEnum.BLACK_BY_FRIEND.getCode());
			userContent.setCreateTime(currentDate);
			userContent.setLastUpdateTime(currentDate);
			this.userContactMapper.insertOrUpdate(userContent);
		}

	}

}